<!-- 指令树 -->
<template>
  <div>
    <div class="treeRightMenu">
      <el-input placeholder="输入关键字进行过滤" clearable v-model="filterText" prefix-icon="Search"
        style="margin-bottom:10px; width: calc(100% - 30px)"></el-input>
      <el-icon class="refresh-btn my-refresh" @click="getTreeList">
        <RefreshRight />
      </el-icon>
      <div class="body">
        <el-tree class="myTree" :data="treeData" :props="defaultProps" highlight-current node-key="id"
          :filter-node-method="filterNode" ref="myTree" @node-click="handleNodeClick"
          @node-contextmenu="contextmenuHandle" :default-expand-all="true">
          <template #default="{ node, data }">
            <span class="editNode">
              <span>{{ node.label }}</span>
            </span>
          </template>
        </el-tree>
        <!-- 嵌套一层增加触发范围 -->
        <div ref="menuDom" class="tree-menu" @mouseleave="closeMenu">
          <ul ref="treeMenu">
            <li v-if="InfoSelectData.hasChild != '0'" v-hasPermi="['comlbs:orderConfiguration:add']"
              @click="rightMenuHandle('add')">新增</li>
            <li v-if="InfoSelectData.hasChild == '0'" v-hasPermi="['comlbs:orderConfiguration:set']"
              @click="rightMenuHandle('orderConfigEdit')">配置</li>
            <li v-hasPermi="['comlbs:orderConfiguration:edit']"
              @click="rightMenuHandle(InfoSelectData.hasChild == '0' ? 'edit' : 'editList')">修改</li>
            <li v-hasPermi="['comlbs:orderConfiguration:remove']" @click="rightMenuHandle('delete')">删除</li>
          </ul>
        </div>
      </div>
    </div>

    <!-- 左侧树的增删查改 -->
    <el-dialog :title="parentName" v-model="editOpen" width="500px" append-to-body>
      <el-form ref="editRef" :model="InfoSelectData" :rules="rules" label-width="120px">
        <!-- 父节点的表单 -->
        <div v-if="showWhich == 'add' || showWhich == 'edit'">
          <el-form-item label="指令名称" prop="orderName">
            <el-input v-model="InfoSelectData.orderName"></el-input>
          </el-form-item>
          <el-form-item label="指令类型" prop="orderType">
            <el-input v-model="InfoSelectData.orderType"></el-input>
          </el-form-item>
          <el-form-item label="是否等待应答" prop="response">
            <el-select v-model="InfoSelectData.response" class="dragSelectBlur">
              <el-option label="是" :value='1'></el-option>
              <el-option label="否" :value='0'></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="是否通用应答" prop="isNormal">
            <el-select v-model="InfoSelectData.isNormal" class="dragSelectBlur">
              <el-option label="是" :value='1'></el-option>
              <el-option label="否" :value='0'></el-option>
            </el-select>
          </el-form-item>
        </div>
        <!-- 分组的表单 -->
        <div v-else>
          <el-form-item label="分组名称：" prop="orderName">
            <el-input v-model="InfoSelectData.orderName"></el-input>
          </el-form-item>
        </div>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitClick">确 定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { getOrderConfigTreeList, updateOrderConfiguration, addOrderConfiguration, delOrderConfiguration } from "@/api/comlbs/orderConfiguration";
const defaultProps = ref({
  children: 'children',
  label: 'orderName',
  isLeaf: 'hasChild'
});
const props = defineProps({
  setSelOption: { type: Function },
  leftTreeNodeClick: { type: Function },
  orderConfigEditHandle: { type: Function },
  setConfigState: { type: Function },
});
const { proxy } = getCurrentInstance();
// 左侧树
const treeData = ref([]);
const filterText = ref('');
const myTree = ref();
const menuDom = ref();
const treeMenu = ref();
const InfoSelectData = ref({});
const parentName = ref(null); //子节点添加展示上级节点
const showWhich = ref('')
const editOpen = ref(false)
const rules = ref({
  orderName: [
    { required: true, message: "请输入名称", trigger: "blur" },
    { min: 0, max: 30, message: "长度在0到30个字符", trigger: "blur" },
  ],
  orderType: [
    { required: true, message: "请输入类型", trigger: "blur" },
  ],
  response: [
    { required: true, message: "请选择是否等待应答", trigger: "blur" },
  ],
  isNormal: [
    { required: true, message: "请选择是否通用应答", trigger: "blur" },
  ],
})

//过滤树节点
function filterNode(value, data) {
  if (!value) return true;
  return data[defaultProps.value.label].indexOf(value) !== -1;
}
function handleNodeClick(data) {
  InfoSelectData.value = data;
  props.leftTreeNodeClick(data)
}

function closeMenu() {
  menuDom.value.classList.remove('active');
}
function rightMenuHandle(type) {
  closeMenu();
  const data = InfoSelectData.value;
  showWhich.value = type;
  switch (type) {
    case 'add':
    case 'addList':
      editOpen.value = true
      InfoSelectData.value = {};
      InfoSelectData.value.parentId = data.id;
      parentName.value = data.orderName + '-' + (type == "add" ? '添加节点' : '添加分组')
      break;
    case 'delete':
      editOpen.value = false
      deleteInfo(data.id);
      break;
    case 'edit':
    case 'editList':
      editOpen.value = true
      InfoSelectData.value = JSON.parse(JSON.stringify(data));
      parentName.value = data.orderName + '-' + (type == "edit" ? '编辑节点' : '编辑分组')
      break;
    case 'orderConfigEdit':
      editOpen.value = false
      props.orderConfigEditHandle(data.orderName, data.confValue, type);
      break;
  }
}

function contextmenuHandle(e, data, node) {
  // type -1：根节点   0:公司    1:部门   2：车  5:围栏
  InfoSelectData.value = data;
  const menu = treeMenu.value;
  menuDom.value.classList.add('active');

  nextTick(() => {
    const menuHeight = menu.clientHeight
    const menuWidth = menu.clientWidth
    const x = e.pageX // 触发节点到页面窗口左边的距离
    const y = e.pageY  // 触发节点到页面窗口顶部的距离

    // 如果会超出屏幕右边则停靠屏幕右边
    const rightNum = window.innerWidth - x;
    if (rightNum >= menuWidth) {
      menuDom.value.style.right = rightNum - menuWidth - 40 + 'px'
    } else {
      menuDom.value.style.right = '-40px'
    }

    // 如果会超出屏幕下边则停靠屏幕下边
    const rightTreeDomHeight = document.getElementById('leftTreeDom').clientHeight;
    const topFixHeight = document.getElementsByClassName('top-block')[0].clientHeight;
    const bottomNum = rightTreeDomHeight - (y - topFixHeight);
    if (bottomNum >= menuHeight) {
      menuDom.value.style.top = y - topFixHeight + 120 + 'px'
    } else {
      menuDom.value.style.top = rightTreeDomHeight - menuHeight + 'px';
    }
  })
}

function getTreeList() {
  getOrderConfigTreeList().then(result => {
    if (result.code == 200) {
      treeData.value = result.data;
      props.setSelOption('nameOptions', result.data[0].children);
      nextTick(() => {
        myTree.value.filter(filterText.value);
      })
    }
  });
}
// 修改/配置指令
function editInfo() {
  let postData = JSON.stringify(InfoSelectData.value);
  updateOrderConfiguration(postData).then(function (response) {
    if (response.code == 200) {
      //刷新左侧表格
      getTreeList();
      showWhich.value = "";
      editOpen.value = false;
      props.setConfigState("");
      proxy.$modal.msgSuccess("信息保存成功！");
    }
  })
}
// 新增指令
function addInfo() {
  let postData = JSON.stringify(InfoSelectData.value);
  addOrderConfiguration(postData).then(function (response) {
    if (response.code == 200) {
      //刷新左侧表格
      getTreeList();
      showWhich.value = "";
      editOpen.value = false;
      props.setConfigState("");
      proxy.$modal.msgSuccess("信息添加成功！");
    }
  })
}
//删除提交
function deleteInfo(id) {
  proxy.$modal.confirm("此操作将删除该项, 是否继续?", "提示").then(() => {
    delOrderConfiguration(id).then(function (response) {
      if (response.code == 200) {
        //刷新左侧表格
        getTreeList();
        proxy.$modal.msgSuccess("删除成功");
      }
    })
  })
}
function submitClick() {
  proxy.$refs['editRef'].validate((valid) => {
    if (valid) {
      switch (showWhich.value) {
        case "add":
          //hasChild表示有无子节点，1是父节点
          InfoSelectData.value.hasChild = 0;
          InfoSelectData.value.confValue = [];
          addInfo();
          break;
        case "addList":
          InfoSelectData.value.hasChild = 1;
          addInfo();
          break;
        case "edit":
          editInfo();
          break;
        case "editList":
          editInfo();
          break;
        default:
          break;
      }
    } else {
      return;
    }
  })
}

getTreeList();

watch(() => filterText, (val) => {
  myTree.value.filter(val);
})

defineExpose({
  InfoSelectData,
  editInfo
})
</script>

<style lang="scss" scoped>
.treeRightMenu {
  padding: 20px;
  box-sizing: border-box;

  .body {
    width: 100%;
    height: calc(100% - 60px);
    overflow: auto;
  }

  .myTree {
    font-size: 14px;

    div {
      display: inline-block;
    }

    .tree-dropdown {
      margin-left: auto;
      margin-right: 10px;
    }

    :v-deep(.el-tree-node) {
      position: relative;
    }

    .el-tree-node__content {
      &:hover {
        .editDom {
          visibility: visible;
        }

        background: #e5efff !important;
        color: #666666;
      }

      .editDom {
        color: #0066ff;
        cursor: pointer;
        visibility: hidden;
      }
    }
  }

  .tree-menu {
    position: fixed;
    visibility: hidden;
    color: #223355;
    font-size: 14px;
    padding: 0 40px;

    ul {
      width: 100px;
      border: 1px solid #DEDEDF;
      border-radius: 6px;
      background-color: #ffffff;
      box-shadow: 0 6px 24px #F4F5F5;
      padding: 8px 2px;
      box-sizing: border-box;
    }

    li {
      text-align: center;
      line-height: 32px;
      cursor: pointer;

      &:hover {
        background-color: #D6EDFF;
        color: #3388FF;
      }
    }

    &.active {
      visibility: visible;
      z-index: 2;
    }
  }
}
</style>
